/**
 * 
 */
package com.onlinemathuracrud.dao.genericdao.impl;

import java.io.Serializable;
import java.util.List;

import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.onlinemathuracrud.dao.genericdao.GenericDao;

/**
 * @author Amit Kashyap
 * @createdDate Sep 7, 2013
 * @createdTime 2:40:44 AM
 */

public abstract class GenericDaoImpl<E, PK extends Serializable> implements GenericDao<E, PK> {
	
	protected HibernateTemplate template = null;

    /**
     * Sets Hibernate session factory and creates a 
     * <code>HibernateTemplate</code> from it.
     */
	@Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.template = new HibernateTemplate(sessionFactory);
     //   template.setCacheQueries(true);
        System.out.println("setSessionFactory entity class============>"+this.getEntityClass()+"and cachequeries============>"+template.isCacheQueries());
    }

	@SuppressWarnings("unchecked")
	public PK save(E newInstance) {

		return (PK) template.save(newInstance);

	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public E findById(PK id) {
	//	System.out.println("findById=====>by "+this.getEntityClass()+" and ======>"+template.isCacheQueries());
		return (E) template.get(getEntityClass(), id);

	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public List<E> findAll() {
	//	System.out.println("findAll=======>by "+this.getEntityClass()+" and ======>"+template.isCacheQueries());
		return template.findByCriteria(createDetachedCriteria());
	}

	@SuppressWarnings("unchecked")
	public List<E> findAllByProperty(String propertyName, Object value) {

		DetachedCriteria criteria = createDetachedCriteria();

		criteria.add(Restrictions.eq(propertyName, value));

		return template.findByCriteria(criteria);

	}

	public List<E> findByExample(E object) {

		List<E> resultList = template.findByExample(object, 0, 1);

		return resultList;

	}

	public List<E> findByExample(E object, int firstResult, int maxResults) {

		List<E> resultList = template.findByExample(object, firstResult, maxResults);

		return resultList;

	}

	public void update(E transientObject) {

		template.update(transientObject);

	}

	public void saveOrUpdate(E transientObject) {

		template.saveOrUpdate(transientObject);

	}
	
	public void merge(E transientObject) {

		template.merge(transientObject);

	}

	public void delete(E persistentObject) {

		template.delete(persistentObject);

	}

	protected abstract Class<E> getEntityClass();

	protected DetachedCriteria createDetachedCriteria() {

		return DetachedCriteria.forClass(getEntityClass());

	}
	
	public void printStatics()
	{
		System.out.println("********************Hibernate Statics Start***************************");
		System.out.println(template.getSessionFactory().getStatistics());
	}

}
